package com.wwj.core.pay.bbn.service.impl;

import com.wwj.core.pay.bbn.BBNPaySDKConfig;
import com.wwj.core.pay.bbn.service.IBBNPayService;
import com.wwj.core.pay.weixin.refund.MD5Util;
import com.wwj.utils.http.HttpUtil;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

@Service
public class BBNPayServiceImpl implements IBBNPayService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public Map<String, String> placeOrder(Map<String, Object> paraMap) {
        Map<String, String> ret = new HashMap<String, String>();
        try {
            //下单参数JSON对象
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("appid", BBNPaySDKConfig.APP_ID);
            jsonObject.put("goodsid", paraMap.get("goodsid"));
            jsonObject.put("pcorderid", paraMap.get("orderid"));
            jsonObject.put("money", paraMap.get("money"));
            jsonObject.put("currency", "CHY");
            jsonObject.put("pcuserid", paraMap.get("playerid"));
            jsonObject.put("notifyurl", paraMap.get("notifyurl"));

            //下单参数字符串,MD5加密
            TreeMap<String,Object> orderParams = new TreeMap<String,Object>();
            orderParams.put("appid", BBNPaySDKConfig.APP_ID);
            orderParams.put("goodsid", paraMap.get("goodsid"));
            orderParams.put("pcorderid", paraMap.get("orderid"));
            orderParams.put("money", paraMap.get("money"));
            orderParams.put("currency", "CHY");
            orderParams.put("pcuserid", paraMap.get("playerid"));
            orderParams.put("notifyurl", paraMap.get("notifyurl"));
            String paraBuff = generateParamsStrInOrder(orderParams);
            paraBuff += String.format("key=%s", BBNPaySDKConfig.APP_KEY);

            //下单参数
            String transdata = URLEncoder.encode(jsonObject.toString(), "UTF-8");
            String sign = URLEncoder.encode(MD5Util.MD5Encode(paraBuff, "UTF-8"), "UTF-8");
            String signtype = "MD5";

            //发送HTTP请求，请求下单
            String respData = HttpUtil.httpRequest(BBNPaySDKConfig.H5_ORDER_URL, "POST", "transdata=" + transdata + "&" + "sign=" + sign + "&" + "signtype=" + signtype);
            if(respData == null) {
                ret.put("success", "false");
                ret.put("code", "0");
                ret.put("errmsg", "请求BBN下单失败");
                return ret;
            }
            respData = URLDecoder.decode(respData, "UTF-8");
            JSONObject jsonResp = getTransData(respData);
            String transId;
            if(jsonResp == null) {
                logger.error("下单失败[" + paraMap.get("orderid") + "]：" + respData);
                ret.put("success", "false");
                ret.put("code", "0");
                ret.put("errmsg", "未知原因:" + respData);
                return ret;
            } else {
                if(!jsonResp.containsKey("code")) {
                    ret.put("success", "false");
                    ret.put("code", "0");
                    ret.put("errmsg", "未知原因:" + respData);
                    return ret;
                }
                int code = jsonResp.getInt("code");
                if(code != 200) {
                    ret.put("success", "false");
                    ret.put("code", code + "");
                    if(jsonResp.containsKey("errmsg")) {
                        ret.put("errmsg", jsonResp.getString("errmsg"));
                    } else {
                        ret.put("errmsg", "未知原因:" + respData);
                    }
                    return ret;
                }
                if(!jsonResp.containsKey("transid")) {
                    ret.put("success", "false");
                    ret.put("code", "0");
                    ret.put("errmsg", "未知原因:" + respData);
                    return ret;
                }
                transId = jsonResp.getString("transid");
            }

            //支付地址参数JSON对象
            JSONObject payJson = new JSONObject();
            payJson.put("appid", BBNPaySDKConfig.APP_ID);
            payJson.put("backurl", paraMap.get("backurl"));
            payJson.put("transid", transId);
            payJson.put("paytype", paraMap.get("paytype"));

            //支付参数转化成map对象,生成字符串，然后MD5加密
            TreeMap<String,Object> payParams = new TreeMap<String,Object>();
            payParams.put("appid", BBNPaySDKConfig.APP_ID);
            payParams.put("paytype", 1);
            payParams.put("transid", transId);
            payParams.put("backurl", paraMap.get("backurl"));
            String md5Str = generateParamsStrInOrder(payParams);
            md5Str += String.format("key=%s", BBNPaySDKConfig.APP_KEY);
            String md5 = MD5Util.MD5Encode(md5Str, "UTF-8");

            //支付地址参数
            String payTransdata = URLEncoder.encode(payJson.toString(), "UTF-8");
            String paySign = URLEncoder.encode(md5, "UTF-8");
            String paySigntype = "MD5";

            //生成支付地址
            String payUrl = BBNPaySDKConfig.H5_PAY_URL + "?" + "data=" + payTransdata + "&" + "sign=" + paySign + "&" + "signtype=" + paySigntype;
            ret.put("success", "true");
            ret.put("payUrl", Base64.encodeBase64String(payUrl.getBytes()));
            ret.put("transId", transId);
            return ret;
        } catch (Exception e) {
            e.printStackTrace();
            ret.put("success", "false");
            ret.put("code", "0");
            ret.put("errmsg", "未知原因:" + e.getMessage());
            return  ret;
        }
    }

    private JSONObject getTransData(String respText) {
        if(respText == null) {
            return null;
        }

        String[] pairs = respText.split("&");
        if(pairs == null) {
            return null;
        }

        String transdata = pairs[0];
        if(transdata == null) {
            return null;
        }

        int idx = transdata.indexOf("=");
        if(idx <= 0) {
            return null;
        }

        String _transdata = transdata.substring(idx + 1);
        if(_transdata == null) {
            return null;
        }

        JSONObject transdataJson = JSONObject.fromObject(_transdata);
        if(transdataJson == null) {
            return null;
        }

        return transdataJson;
    }

    public String generateParamsStrInOrder(TreeMap<String, Object> paraMap) {
        try {
            StringBuilder buff = new StringBuilder();
            for (Map.Entry<String, Object> param : paraMap.entrySet()) {
                if (StringUtils.isNotBlank(param.getKey())) {
                    String key = param.getKey();
                    Object val = param.getValue();
                    buff.append(key).append("=").append(val).append("&");
                }
            }
            return buff.toString();
        } catch (Exception e) {
            return null;
        }
    }
}
